package com.cloud.transaction.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;

@Aspect
@Component
public class MapperAspect {

    // 定义切点，拦截所有在com.cloud.mapper包下的接口方法
    @Pointcut("execution(* com.cloud.mapper.*.*(..))")
    public void mapperMethods() {
    }

    // 环绕通知，在方法执行前后加上逻辑
    @Around("mapperMethods()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法参数
        Object[] args = joinPoint.getArgs();

        // 记录方法开始
        System.out.println("Method " + joinPoint.getSignature().getName() + " is called with arguments: " + args);

        // 执行目标方法
        Object result = joinPoint.proceed();

        // 记录方法执行结束
        System.out.println("Method " + joinPoint.getSignature().getName() + " finished with result: " + result);
        transCallBack();
        // 返回方法的执行结果
        return result;
    }

    void transCallBack() {
        if (TransactionSynchronizationManager.isActualTransactionActive()) {
            // 注册事务同步回调
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                @Override
                public void afterCommit() {
                    System.out.println("事务提交后处理业务逻辑");
                    // 在事务提交后执行的逻辑
                    // 可以进行一些清理工作或发送通知
                    // 发送通知、记录成功信息、异步执行后续任务、清理事务相关的临时数据等。
                }

                // 一般用这个
                @Override
                public void afterCompletion(int status) {
                    // 事务完成后（无论事务是提交还是回滚
                    // status表示事务的状态，可以根据不同状态执行不同的操作
                    System.out.println(status);
                    if (status == STATUS_COMMITTED) {
                        System.out.println("Transaction committed successfully.");
                        // 执行事务成功提交后的逻辑
                    } else if (status == STATUS_ROLLED_BACK) {
                        System.out.println("Transaction rolled back.");
                        // 执行事务回滚后的逻辑
                    } else if (status == STATUS_UNKNOWN) {
                        System.out.println("Transaction status is unknown.");
                        // 处理事务状态未知的情况
                    }
                }

                @Override
                public void beforeCommit(boolean readOnly) {
                    // 在事务提交前执行的逻辑
                    // readOnly表示事务是否为只读
                    //可以在事务提交前检查数据的一致性、验证某些条件是否满足、修改事务的状态等。
                    System.out.println("事务提交前处理业务逻辑beforeCommit");
                }

                @Override
                public void beforeCompletion() {
                    // 事务完成前（即提交或回滚之前）,这是事务完成之前的回调方法，不管事务是提交还是回滚都会被调用。
                    // 执行一些清理操作，或者在事务提交/回滚前最后检查某些资源或状态
                    System.out.println("事务完成前处理业务逻辑beforeCompletion");
                }
            });
        }
    }
}
